local skel = fk.CreateSkill {
  name = "emo__zhexing",
  tags = {Skill.Compulsory},
  dynamic_desc = function (self, player, lang)
    local mark = player:getMark("emo__zhexing_record")
    if type(mark) == "table" and #mark > 0 then
      return "emo__zhexing_dyn:" ..
      table.concat(table.map(mark, function (dat)
        return "【".. Fk:translate(Fk:getCardById(dat[1]).name, lang) .. "】-〖" .. Fk:translate(dat[2], lang) .. "〗"
      end), "；")
    end
  end,
}

Fk:loadTranslationTable{
  ["emo__zhexing"] = "磔形",
  [":emo__zhexing"] = "锁定技，游戏开始时，将一张<a href=':dismember'>【碎尸】</a>置入装备区。你的装备牌技能无效，改为随机转化技。当你使用时，随机改变之。若你转化了牌，你摸一张牌。当你受到伤害后，你获得一张非基本牌。",

  [":emo__zhexing_dyn"] = "锁定技，游戏开始时，将一张【碎尸】置入装备区。你的装备牌技能无效，改为随机转化技。当你使用时，随机改变之。若你转化了牌，你摸一张牌。当你受到伤害后，你获得一张非基本牌。<br>已记录：{1}",

  ["$emo__zhexing1"] = "啊",
  ["$emo__zhexing2"] = "呃",
  ["$emo__zhexing3"] = "嗯",
}

skel:addEffect(fk.GameStart, {
  anim_type = "drawcard",
  can_trigger = function (self, event, target, player, data)
    return player:hasSkill(skel.name)
  end,
  on_use = function (self, event, target, player, data)
    local room = player.room
    local card = room:printCard("dismember", Card.Spade, 1)
    room:moveCardIntoEquip(player, card.id, skel.name, true, player)
  end,
})

local source_skill = nil --- 无语

--- 获取新的转化技能
---@param room Room
---@return string?
local function getVSSkill(room)
  local skills = room:getTag("emo__zhexing_skills")---@type string[]
  if skills == nil then
    skills = {}
    -- 技能禁池
    local ban_skills = {
      "liangyuan" , "zhangdeng" , "danying", "fengying" , "lingyin" , "zhenyi", "jibing", "fuping",
      "ty__fanghun", "fanghun", "os__fanghun", "guhuo", "ol_ex__guhuo", "m_ex__guhuo",
      "steam__exi",
    }
    local acceptableEvents = {fk.CardUsing, fk.CardUseFinished, fk.TargetSpecified, fk.TargetSpecifying, fk.AfterCardTargetDeclared,
    fk.CardResponding, fk.CardRespondFinished}
    --- 排除一些主技能实际上是触发技的转化技能，例如双雄
    --- 除了延时效果，禁止出现触发技效果
    ---@param skill Skill
    local triggerCheck = function (skill)
      return not table.find(skill.related_skills, function(s)
        return s:isInstanceOf(TriggerSkill) and
        (not s.is_delay_effect or (s.event and table.contains(acceptableEvents, s.event)))
      end)
    end
    --- 筛选掉复杂的泛转化技。只允许单牌转化
    ---@param skill ViewAsSkill
    local vsCheck = function (skill)
      local skeleton = skill:getSkeleton()
      return not (type(skill.pattern) == "string" and string.find(skill.pattern, "|")) and skill.pattern ~= "." -- 禁止泛转化
      --and skill.interaction == nil -- 不要误杀了，俩牌也可以用这框
      and skeleton and skeleton.attached_skill_name == nil -- 禁止让别人发动
    end
    local generals = table.simpleClone(room.general_pile)
    -- 防止武将将太少，加个白名单吧
    --[[
    local whitelist_pack = {"standard", "shzl", "yj", "sp"}
    for _, pkg in ipairs(whitelist_pack) do
      local pack = Fk.packages[pkg]
      if pack then
        table.insertTable(generals, table.map(pack.generals, Util.NameMapper))
      end
    end
    --]]
    for _, name in ipairs(generals) do
      local general = Fk.generals[name]
      for _, s in ipairs(general:getSkillNameList()) do
        local skill = Fk.skills[s]
        if skill:isInstanceOf(ViewAsSkill) and not table.contains(ban_skills, skill.name) and triggerCheck(skill) and vsCheck(skill) then
          if table.every({Skill.Switch, Skill.Limited, Skill.Quest, Skill.Wake, Skill.Rhyme, Skill.AttachedKingdom},
           function (t) return not skill:hasTag(t) end) then
            table.insertIfNeed(skills, skill.name)
          end
        end
      end
    end
    room:setTag("emo__zhexing_skills", skills)
  end
  local exists = {}
  for _, p in ipairs(room.players) do
    table.insertTable(exists, table.map(p:getAllSkills(), Util.NameMapper))
  end
  local availableSkills = table.filter(skills, function (s)
    return not table.contains(exists, s)
  end)
  if #availableSkills > 0 then
    return table.random(availableSkills)
  end
end

--- 更新拥有的技能
---@param player  ServerPlayer
local function refreshSkill(player)
  local room = player.room
  local record = player:getTableMark("emo__zhexing_record")
  local map = {}
  for _, dat in ipairs(record) do
    map[dat[1]] = dat[2]
  end
  local new_mark = {}
  for _, id in ipairs(player:getCardIds("e")) do
    local skill = map[id] or getVSSkill(room)
    if skill then
      table.insert(new_mark, {id, skill})
    end
    map[id] = nil
  end
  room:setPlayerMark(player, "emo__zhexing_record", new_mark)
  for _, skill in pairs(map) do
    if Fk.skills[skill] ~= nil then
      room:handleAddLoseSkills(player, "-"..skill, source_skill, false, true)
    end
  end
  for _, dat in ipairs(new_mark) do
    room:handleAddLoseSkills(player, dat[2], source_skill, false, true)
  end
end

skel:addEffect(fk.AfterCardsMove, {
  can_refresh = function(self, event, target, player, data)
    if not player:hasSkill(skel.name, true) then return false end
    for _, move in ipairs(data) do
      if move.toArea == Card.PlayerEquip and move.to == player then
        return true
      end
      if move.from == player and table.find(move.moveInfo, function (info)
        return info.fromArea == Card.PlayerEquip
      end) then
        return true
      end
    end
  end,
  on_refresh = function (self, event, target, player, data)
    refreshSkill(player)
  end,
})

skel:addAcquireEffect(function (self, player, is_start)
  if not is_start then
    refreshSkill(player)
  end
end)

skel:addLoseEffect(function (self, player, is_death)
  local mark = player:getTableMark("emo__zhexing_record")
  if type(mark) ~= "table" then return end
  for _, dat in ipairs(mark) do
    if Fk.skills[dat[2]] ~= nil then
      player.room:handleAddLoseSkills(player, "-"..dat[2], source_skill, false, true)

    end
  end
  player.room:setPlayerMark(player, "emo__zhexing_record", 0)
end)

--- 让记录的装备牌技能无效
skel:addEffect("invalidity", {
  invalidity_func = function (self, player, skill)
    local mark = player:getMark("emo__zhexing_record")
    if type(mark) ~= "table" then return false end
    for _, dat in pairs(mark) do
      local id = dat[1]
      if id and table.contains(player:getCardIds("e"), id) then
        local card = Fk:getCardById(id, true) ---@type EquipCard
        if card.type == Card.TypeEquip then
          local skills = card:getEquipSkills(player)
          if table.contains(skills, skill) then
            return true
          end
        end
      end
    end
  end,
})


local change_can_trigger = function(self, event, target, player, data)
  if player:hasSkill(skel.name) and target == player then
    for _, dat in ipairs(player:getTableMark("emo__zhexing_record")) do
      if table.contains(data.card.skillNames, dat[2]) then
        return true
      end
    end
  end
end

--- 转换技能，并可能摸一张牌
---@param player ServerPlayer
local change_on_use = function (self, event, target, player, data)
  local room = player.room
  local mark = player:getTableMark("emo__zhexing_record")
  for i, dat in ipairs(player:getTableMark("emo__zhexing_record")) do
    local id, skill = table.unpack(dat)
    if table.contains(data.card.skillNames, skill) then
      room:handleAddLoseSkills(player, "-"..skill, source_skill, false, true)
      local new = getVSSkill(room)
      if new then
        mark[i] = {id, new}
        room:handleAddLoseSkills(player, new, source_skill, false, true)
      end
      break
    end
  end
  room:setPlayerMark(player, "emo__zhexing_record", mark)
  if player:isAlive() and #data.card.subcards > 0 then
    player:drawCards(1, skel.name)
  end
end

--- 使用转化技能后，改变技能，并可能摸牌
skel:addEffect(fk.CardUsing, {
  anim_type = "drawcard",
  can_trigger = change_can_trigger,
  on_cost = Util.TrueFunc,
  on_use = change_on_use,
})

skel:addEffect(fk.CardResponding, {
  anim_type = "drawcard",
  can_trigger = change_can_trigger,
  on_cost = Util.TrueFunc,
  on_use = change_on_use,
})

skel:addEffect(fk.Damaged, {
  anim_type = "masochism",
  on_cost = Util.TrueFunc,
  on_use = function (self, event, target, player, data)
    local room = player.room
    local ids = room:getCardsFromPileByRule(".|.|.|.|.|trick,equip")
    if #ids > 0 then
      room:obtainCard(player, ids, true, fk.ReasonJustMove, player, skel.name)
    end
  end,
})

--- FIXME：目前BUG：火扇子八卦阵不被无效，马不能被无效，断手的手牌上限可以无效，但是有时候有效

return skel
